/**
 * 开单、修改订单页
 * 此页面进入的方式有：1.从订单列表点开单、修改进入 2.其他页面跳转进入 3.甲方页面跳转进入
 */
import { ExclamationCircleOutlined } from '@ant-design/icons';
import React, { useEffect, useRef, useState } from 'react';
import { PageContainer } from '@ant-design/pro-layout';
import { Divider, Modal, FormInstance, message, Spin } from 'antd';
import ItemInfo from './ItemInfo';
import EyeInfo, { eyeInfoColumn } from './EyeInfo';
import SettlementInfo from './SettlementInfo';
import PayDialog from './PayDialog';
import { Prompt } from 'react-router';
import { useModel } from 'umi';
import {
  createOnceOrder,
  updateOnceOrder,
  getOnceOrderDetail,
  cancelOrder
} from '@/services/order/api';
import {
  getGoodsSpecsList
} from '@/services/stock-goods/api';
import { MsgType, showMsg, isNull } from '@/utils/utils';
import { history } from 'umi';
import './style.less';
import BreadcrumbDept from '@/components/BreadcrumbDept';
import ChoicePatient from '@/components/ChoicePatient';
import Detail from './Detail';
import { getPatientLevelInfo } from '@/services/patient/levelApi';

const { confirm } = Modal;

let timerId; // 定时查询支付状态

interface DoctorBillProps {
  location?: any;
}

const DoctorBill: React.FC<DoctorBillProps> = (props) => {
  const { location } = props;
  const { query } = location;
  const { type, order_id, eventNo } = query; // type: add=开单，edit=修改订单，reopen=重新开单， order_id：订单编号，eventNo=病案号/身份证号/住院号（一般是在甲方系统点进来进行开单操作）
  const { initialState } = useModel('@@initialState'); // 获得当前登录账号的一些信息
  const formRef = useRef<FormInstance>();
  const goodsRef = useRef(); // 获取商品信息的实例
  const eyeRef = useRef(); // 获取验光信息信息的实例
  const settRef = useRef(); // 获取结算信息的实例
  const patientRef = useRef(); // 获得患者信息的实例
  const [printing, setPrinting] = useState(false); // 是否打印

  const [loading, setLoading] = useState(false);

  // 患者信息
  const [patientInfo, setPatientInfo] = useState<ORDERAPI.PatientInfo>({} as ORDERAPI.PatientInfo);
  // 商品列表
  const [goodsList, setGoodsList] = useState<STOCKGOODSAPI.GoodsItem[]>([]);
  // 原始商品列表，用于还原数据
  const [yuanGoodsList, setYuanGoodsList] = useState<STOCKGOODSAPI.GoodsItem[]>([]);

  // 患者等级信息
  const [patientLevelInfo, setPatientLevelInfo] = useState<any>();
  // 结算信息
  const [settleInfo, setSettleInfo] = useState<any>({});
  // 支付弹窗
  const [payDialogVisible, setPayDialogVisible] = useState<boolean>(false);
  // 订单详情
  const [orderDetail, setOrderDetail] = useState({});

  // 详情弹窗
  const [detailVisible, setDetailVisible] = useState<boolean>(false);

  // 是否已支付
  const [isPay, setIsPay] = useState(false);

  // 根据商品id、部门编号获得商品规格
  const getSpe = (goods_id, goods_dept_code) => {
    return new Promise(async (resolve, reject) => {
      const data: STOCKGOODSAPI.GoodsSpecsItemList = await getGoodsSpecsList({ goods_id, goods_dept_code, current: 1, pageSize: 10000 });
      resolve(data.record_list || []);
    });
  }

  useEffect(() => {
    init();
  }, [order_id]);

  // 重置页面，更换患者保存后调用
  const resetPage = () => {
    patientRef.current.clear();
    goodsRef.current.clear();
    settRef.current.clear();
  }

  // 10s轮询一次支付结果
  const timer = () => {
    timerId = setInterval(() => refreshOrder(false), 10000);
  }

  // 刷新订单信息
  const refreshOrder = () => {
    getOnceOrderDetail(order_id).then(data => {
      // 已支付状态停止轮询
      if (data.order_status === 'P') {
        // console.log('timer', timerId, data.order_status)
        clearInterval(timerId);
        timerId = null;
      }
      // 不等于以下状态时，则当作已支付
      if (data.order_status !== 'C' && data.order_status !== 'W' && data.order_status !== 'E') {
        setIsPay(true);
      }
      // 待支付状态需要10s轮询
      if (data.order_status === 'W') {
        clearInterval(timerId)
        timerId = null;
        timer();
      }
    });
  }

  const init = () => {
    // 有订单号，查询订单详情
    if (order_id) {
      setLoading(true);
      getOnceOrderDetail(order_id).then(data => {
        setLoading(false);
        setOrderDetail(data);
        // dept_type 科室类型 Y：眼科
        if (initialState?.currentUser?.dept_type === 'Y') {
          eyeRef?.current?.reload();
        }
        const patinfo = {
          patient_name: data.patient_name,
          patient_id: data.patient_id,
          identity_no: data.identity_no,
          mobile: data.mobile,
          ic_card_no: data.ic_card_no,
          admission_num: data.admission_num,
          create_dept_name: data.create_dept_name,
          visit_no: data.admission_num,
        };
        // 已支付
        if (data.order_status !== 'C' && data.order_status !== 'W' && data.order_status !== 'E') {
          setIsPay(true);
        }

        // 待支付订单执行轮询
        if (data.order_status === 'W') {
          timer();
        }

        setPatientInfo(patinfo as ORDERAPI.PatientInfo);

        // 给自定义模块的患者信息区域赋值
        patientRef.current?.update(patinfo);

        // 把订单详情已有的商品信息显示出来，需要循环调用接口获取每个商品的规格列表  start
        const apilist = [];
        const goodsList = data.order_goods_list.map((item, key) => {
          apilist.push(getSpe(item.goods_id, item.goods_dept_code));
          return {
            id: item.record_id,
            ...item
          }
        })
        Promise.all(apilist).then(res => {
          res.forEach((element, key) => {
            goodsList[key].specsList = element;
            goodsList[key].disabled = true; // 默认禁用输入框
            const result = element.find(item => item.specs_id === goodsList[key].specs_id);
            if (!isNull(result)) {
              goodsList[key].can_inventory = result.can_inventory // can_inventory：可操作的库存
            }
          });
          setGoodsList(Object.assign([], goodsList));
          setYuanGoodsList(JSON.parse(JSON.stringify(goodsList))); // 用上面的方式没效果，所以换了一种方式
        });
        // 把订单详情已有的商品信息显示出来，需要循环调用接口获取每个商品的规格列表  end

        setSettleInfo({
          ...data,
        });

        formRef.current?.setFieldsValue({
          patient_name: data.patient_name
        });
      })
    } else if (!isNull(eventNo)) { // 单点登录来的住院号，则查询用户信息
      patientRef.current.fetch?.(eventNo)
    }
  }

  // 获得是否需要配镜的初始化数据（此方法眼科科室用）
  const getInitData = () => {
    const eyeValues = eyeRef.current.getFields();
    if (eyeValues.isShow === true) {
      return {}
    }

    return {
      right_degrees: 9999,
      right_astig: 9999,
      right_axial: 9999,
      right_rectify_bef: null,
      right_rectify_af: null,
      left_degrees: 9999,
      left_astig: 9999,
      left_axial: 9999,
      left_rectify_bef: null,
      left_rectify_af: null,
      pup_distance: 9999,
      pup_distance_right: null,
      pup_distance_left: null,
      pup_high_right: null,
      pup_high_left: null,
      madd: null,
      special_case: null,
      service_price: 0,
      sight_no: null,
      optician_id: null,
      optician_name: null,
      doctor_id: null,
      doctor_name: null
    }
  }

  // 提交表单前的表单验证
  const checkForm = (values) => {
    // 没有患者信息
    if (!patientInfo.patient_name) {
      showMsg('请先输入患者信息', MsgType.INFO);
      return false;
    }

    // 商品信息
    if (!goodsList.length) {
      showMsg('请添加商品信息', MsgType.INFO);
      return false;
    }
    // 眼科下单的判断
    if (initialState?.currentUser?.dept_type === 'Y') {
      const eyeValues = eyeRef.current.getFields();
      if (!isNull(eyeValues.right_degrees) && isNaN(eyeValues.right_degrees)) {
        message.error('右眼球镜输入有误，请修改');
        return false;
      }
      if (!isNull(eyeValues.right_astig) && isNaN(eyeValues.right_astig)) {
        message.error('右眼柱镜输入有误，请修改');
        return false;
      }
      if (!isNull(eyeValues.right_axial) && isNaN(eyeValues.right_axial)) {
        message.error('右眼轴位输入有误，请修改');
        return false;
      }
      if (!isNull(eyeValues.before_right_version) && isNaN(eyeValues.before_right_version)) {
        message.error('右眼矫正前输入有误，请修改');
        return false;
      }
      if (!isNull(eyeValues.after_right_version) && isNaN(eyeValues.after_right_version)) {
        message.error('右眼矫正后输入有误，请修改');
        return false;
      }
      if (!isNull(eyeValues.left_degrees) && isNaN(eyeValues.left_degrees)) {
        message.error('左眼球镜输入有误，请修改');
        return false;
      }
      if (!isNull(eyeValues.left_astig) && isNaN(eyeValues.left_astig)) {
        message.error('左眼柱镜输入有误，请修改');
        return false;
      }
      if (!isNull(eyeValues.left_axial) && isNaN(eyeValues.left_axial)) {
        message.error('左眼轴位输入有误，请修改');
        return false;
      }
      if (!isNull(eyeValues.before_left_version) && isNaN(eyeValues.before_left_version)) {
        message.error('左眼矫正前输入有误，请修改');
        return false;
      }
      if (!isNull(eyeValues.after_left_version) && isNaN(eyeValues.after_left_version)) {
        message.error('左眼矫正后输入有误，请修改');
        return false;
      }
      if (!isNull(eyeValues.pup_distance) && isNaN(eyeValues.pup_distance)) {
        message.error('瞳距输入有误，请修改');
        return false;
      }
    }
    // console.log('values', values)

    // 结算价格
    const js = parseFloat(values.sett_price);
    if (js < 0.01 * values.goodsNum) {
      message.error(`结算价格最少为${0.01 * values.goodsNum}，请修改！`);
      return false;
    }
    return true;
  }

  /**
   * 保存订单，
   * 发起支付
   * @param values
   * @param method
   * @returns
   */
  const onFinish = async (values: any, method: string, noBack?: string) => {
    const eyeValues = eyeRef.current ? eyeRef.current.getFields() : {};
    // console.info('::::::: ', eyeValues);
    if (checkForm(values)) {
      let data = {
        ...patientInfo,
        order_goods_list: goodsList,
        ...values,
        admission_num: patientInfo.visit_no, // 住院号字段单独传入
      }
      console.log('eyeValues', eyeValues);
      
      // 如果眼科科室下单，但并没有开启验光信息按钮，则初始化一些验光信息数据传给接口
      if (!eyeValues.isShow && initialState?.currentUser?.dept_type === 'Y') {
        data = {
          ...data,
          ...eyeValues,
          ...getInitData(),
        }
      } else {
        data = {
          ...data,
          ...eyeValues,
          right_degrees: !isNull(eyeValues.right_degrees) ? parseFloat(eyeValues.right_degrees) : 9999,
          right_astig: !isNull(eyeValues.right_astig) ? parseFloat(eyeValues.right_astig) : 9999,
          right_axial: !isNull(eyeValues.right_axial) ? parseInt(eyeValues.right_axial, 10) : 9999,
          left_degrees: !isNull(eyeValues.left_degrees) ? parseFloat(eyeValues.left_degrees) : 9999,
          left_astig: !isNull(eyeValues.left_astig) ? parseFloat(eyeValues.left_astig) : 9999,
          left_axial: !isNull(eyeValues.left_axial) ? parseInt(eyeValues.left_axial, 10) : 9999,
          pup_distance: !isNull(eyeValues.pup_distance) ? parseFloat(eyeValues.pup_distance) : 9999,
          optician_id: eyeValues.optician_id,
          optician_name: eyeValues.optician_name,
          doctor_id: eyeValues.doctor_id,
          doctor_name: eyeValues.doctor_name
        }
      }
      // console.info('********** ', data);
      if (parseFloat(data.discount_ratio) > 1) {
        message.error('订单折扣不能大于1，请修改！');
        return;
      }
      goodsRef.current.validate().then(async res => {
        // console.log('result', res)
        // console.log('保存param', data, orderDetail);
        // return;
        // 待支付订单修改前要变更订单状态
        if (orderDetail.order_status === 'W') {
          // 这里先调用变更订单状态的方法，状态改为C：开单状态。
          // 状态改完后，才能执行修改订单的操作
          setLoading(true);
          cancelOrder({
            order_id: orderDetail.order_id,
            order_status: 'C'
          }).then(res => {
            // console.log('修改状态回调', res);
            save(method, data, noBack); // 继续保存订单
          }).catch(error => {
            setLoading(false);
            showMsg(error?.data?.errmsg)
          });
          return;
        }
        // return;
        // 表格信息都填写了
        if (res) {
          // 保存订单
          await save(method, data, noBack);
          patientRef.current.clear();
        } else {
          showMsg('您还有未完成的商品信息');
        }
      });
    }
  }

  // 保存订单
  const save = async (method, data, noBack) => {
    // 点击的保存订单
    if (method === 'onSave') {
      // 重新开单||开单
      if (type === 'reopen' || type === 'add') {
        if (data.order_id) {
          delete data.order_id
        }
        setLoading(true);
        createOnceOrder(data).then(() => {
          setLoading(false);
          showMsg('已保存', MsgType.SUCCESS);
          init();
          // 如果地址栏没有eventNo，则保存后跳回到列表页
          if (!isNull(eventNo)) {
            history.replace(`/order/one-time-order`);
          } else if (noBack !== 'noBack') { // 判断是否返回到上一页
            history.goBack()
          } else { // 停留在该页面，并重置页面信息，以方便操作人员输入其他患者信息进行操作
            resetPage();
          }
        }).catch(error => {
          setLoading(false);
          showMsg(error?.data?.errmsg)
        });
      } else if (type === 'edit') { // 修改订单
        data = Object.assign({}, data, { order_id })
        setLoading(true);
        updateOnceOrder(data).then(() => {
          setLoading(false);
          showMsg('已保存', MsgType.SUCCESS);
          init();
          if (noBack !== 'noBack') {
            history.goBack()
          }
        }).catch(error => {
          setLoading(false);
          showMsg(error?.data?.errmsg)
        });
      }

    } else { // 点击的发起支付
      // eslint-disable-next-line no-lonely-if
      // 重新开单||开单
      if (type === 'reopen' || type === 'add') {
        if (data.order_id) {
          delete data.order_id
        }
        setLoading(true);
        createOnceOrder(data).then(res => {
          setLoading(false);
          history.replace(`/order/one-time-order/doctor-bill?order_id=${res.order_id}&type=edit`)
          setSettleInfo(res);
          setPayDialogVisible(true); // 打开支付前确认订单弹窗
        }).catch(error => {
          setLoading(false);
          showMsg(error?.data?.errmsg)
        });

      } else if (type === 'edit') { // 修改订单
        setLoading(true);
        data = Object.assign({}, data, { order_id })
        updateOnceOrder(data).then(res => {
          setLoading(false);
          init();
          setSettleInfo(res);
          setPayDialogVisible(true); // 打开支付前确认订单弹窗
        }).catch(error => {
          setLoading(false);
          showMsg(error?.data?.errmsg)
        });
      }
    }
  }

  // 点击更换患者按钮的提示
  function showConfirm() {
    const result = goodsRef.current.isNull();
    // console.log('result', result);
    // 如果商品信息有录入则提示
    if (!result) {
      confirm({
        title: '当前有未保存的订单信息，是否保存？',
        icon: <ExclamationCircleOutlined />,
        okText: '保存',
        cancelText: '放弃',
        onOk() {
          settRef.current.submit();
          setIsPay(false);
        },
        onCancel() {
          // console.log('Cancel');
          setIsPay(false);
          setPatientInfo({});
          goodsRef.current.clear();
          settRef.current.clear();
          setPatientInfo({});
          patientRef.current.clear();
        },
      });
    } else {
      setPatientInfo({});
      goodsRef.current.clear();
      settRef.current.clear();
      setPatientInfo({});
    }
    setPatientLevelInfo({});
  }

  return (
    <PageContainer title="一次性订单开单" extra={<BreadcrumbDept />} breadcrumb={{}} onBack={() => history.goBack()}>
      <Spin spinning={loading}>
        <div className="service-record">
          <div className="header">
            <div className="title">1.患者信息</div>
          </div>
          <Divider />
          {/* 患者信息自定义组件 */}
          <ChoicePatient
            caseNoKey={initialState?.canAll ? 'out_case_no' : 'case_no'} // 用于判断接口用哪个字段进行查询，带out_的代表接口查询的时候不限制科室查询，如出院办结可用
            ref={patientRef}
            onChoice={(info) => {
              goodsRef.current.addLine(); // 查询到患者后，默认给商品信息添加一行数据
              setPatientInfo(Object.assign({}, info));
              // 查询患者积分折扣信息
              setPatientLevelInfo({});
              getPatientLevelInfo(info.patient_id).then(res => {
                if (res)
                  setPatientLevelInfo(res);
              }).catch(error => showMsg(error?.data?.errmsg));
            }}
            changePatient={showConfirm}
            showMore={false}
            fromTo='onceOrder'
          />
        </div>


        {/* 商品信息区 */}
        <ItemInfo
          ref={goodsRef}
          type={type}
          list={goodsList}
          yuanlist={yuanGoodsList}
          updateGoodsList={setGoodsList}
        />

        {
          // 验光信息区，眼科登录的才展示该区域
          initialState?.currentUser?.dept_type === 'Y' &&
          <EyeInfo
            ref={eyeRef}
            orderObj={orderDetail}
          />
        }

        {/* 结算信息区 */}
        <SettlementInfo
          ref={settRef}
          onSave={onFinish}
          onFinish={onFinish}
          goodsList={goodsList}
          settleInfo={settleInfo}
          levelInfo={patientLevelInfo}
          isPay={isPay}
          type={type}
        />

        {
          // 发起支付前确认订单弹窗
          payDialogVisible && <PayDialog
            patientInfo={patientInfo}
            goodsList={goodsList}
            settleInfo={settleInfo}
            handleModalVisible={setPayDialogVisible}
            reload={(isPrint: Boolean) => {
              setDetailVisible(true);
              setPayDialogVisible(false);
              setPrinting(isPrint);
            }}
          />
        }
        {
          // 查看订单详情弹窗
          detailVisible && <Detail
            isPrint={printing}
            handleModalVisible={() => {
              setDetailVisible(false);
              init();
              // history.goBack();
            }}
            record={orderDetail}
          />
        }

        {/* 页面离开的时候清空计时器 */}
        <Prompt message={(v) => {
          //写判断逻辑等代码
          // console.log('页面离开', v);
          clearInterval(timerId)
          timerId = null;
          return true;//返回true标示离开当前页面;false表示留在当前页面
        }}
        />
      </Spin>
    </PageContainer>
  );
};
export default DoctorBill;
